package com.example.docking.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.example.docking.dao.jindie.GenericDataItem;
import com.example.docking.dao.jindie.ResponseData;
import com.example.docking.dao.jindie.request.CommonOperateDao;
import com.example.docking.dao.jindie.request.PurOrderRequest;
import com.example.docking.dao.jindie.response.*;
import com.example.docking.dao.xky.*;
import com.example.docking.httpXKY.dao.BaseXKYListResponse;
import com.example.docking.httpXKY.dao.BaseXKYObjResponse;
import com.example.docking.httpXKY.httpSend.XKYClient;
import com.example.docking.service.impl.DataServiceImpl;
import com.example.docking.service.impl.SupplierServiceImpl;
import com.example.docking.util.Constants;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.smecloud.apigw.model.ApiResult;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Type;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;

import static com.example.docking.httpXKY.httpSend.XKYClient.ERP_CODE;

/**
 * @author: tengguodong
 * @date: 2025/5/29
 */
@Slf4j
@Controller
public class XKYDJOrderController {
    private final Gson gson = new Gson();

    @SneakyThrows
    public void selectDJOrder() {
        // 1.查询采购答交列表
        List<DJOrderItem> djOrderItemList = selectDJOrderList();
        log.info("采购变更单列表：{}", gson.toJson(djOrderItemList));
        if (CollectionUtils.isEmpty(djOrderItemList)) {
            return;
        }
        for (DJOrderItem djOrderItem : djOrderItemList) {
            // 2.查询采购订单详情
            PurchaseOrderDetail purchaseOrderDetail = selectPurchaseOrderDetail(djOrderItem.getPoErpNo());
            log.info("采购订单详情：{}", JSON.toJSONString(purchaseOrderDetail));
            // 3.查询采购订单详情
            PurOrderDetailData purOrderDetailData = selectERPPurOrderDetail(purchaseOrderDetail.getPoErpNo());
            if (StringUtils.equals("C", purOrderDetailData.getBill_close_state())) {
                continue;
            }
            // 反审核采购订单
            unAuditPurOrder(purOrderDetailData.getId());
            // 4.采购订单推送ERP
            DataServiceImpl service = new DataServiceImpl();
            PurOrderRequest purOrderRequest = new PurOrderRequest();
            purOrderRequest.setId(purOrderDetailData.getId());
            setBillDate(purOrderRequest, purchaseOrderDetail);
            setSupplier(purOrderRequest, purchaseOrderDetail);
            materialEntity(purOrderRequest, purchaseOrderDetail);
            log.info("采购订单推送ERP：{}", JSON.toJSONString(purOrderRequest));
            ApiResult insertResult = service.InsertDataOne(Constants.PUR_ORDER, new HashMap<>(), purOrderRequest);
            log.info("采购订单推送ERP结果：{}", JSON.toJSONString(insertResult));
            auditPurOrder(purOrderDetailData.getId(), service);
            // 4.回执采购订单同步状态
            updateSyncStatus(purchaseOrderDetail, insertResult);
        }
    }

    /**
     * 采购订单审核
     *
     * @param id
     * @param service
     */
    private void auditPurOrder(String id, DataServiceImpl service) {
        List<String> ids = new ArrayList<>();
        ids.add(id);
        CommonOperateDao commonOperateDao = new CommonOperateDao();
        commonOperateDao.setEntity_number(Constants.PUR_BILL_ORDER);
        commonOperateDao.setIds(ids);
        commonOperateDao.setOperate_type(Constants.AUDIT);
        try {
            ApiResult auditData = service.SelectDataAudit(Constants.COMMON_OPERATE, new HashMap<>(), commonOperateDao);
            ResponseData<SaveData> auditResponse = gson.fromJson(auditData.getBody(), new TypeToken<ResponseData<SaveData>>() {
            }.getType());
            if (auditResponse.getErrcode() == 0) {
                log.info("审核采购订单成功, auditResponse = {}", auditResponse);
            } else {
                log.error("审核采购订单失败. auditResponse: {}", auditResponse);
                throw new RuntimeException(auditResponse.getErrcode() + ":" + auditResponse.getDescription());
            }
        } catch (Exception e) {
            log.error("Error occurred while auditing sales order", e);
            throw new RuntimeException(e);
        }
    }

    private static ResponseData unAuditPurOrder(String id) {
        ResponseData responseData = new ResponseData();
        if (id == null || id.equals("")) {
            responseData.setErrcode(100002);
            responseData.setDescription("审核id为空");
            return responseData;
        }
        DataServiceImpl dataService = new DataServiceImpl();
        Gson gson = new Gson();
        List<String> ids = new ArrayList<>();
        ids.add(id);
        HashMap<String, String> map = new HashMap<>();
        log.info("反审核：生产任务单ids: {}", ids);
        CommonOperateDao commonOperateDao = new CommonOperateDao();
        commonOperateDao.setEntity_number(Constants.PUR_BILL_ORDER);
        commonOperateDao.setIds(ids);
        commonOperateDao.setOperate_type(Constants.UNAUDIT);
        ResponseData<SaveData> response = null;
        try {
            ApiResult auditData = dataService.SelectDataAudit(Constants.COMMON_OPERATE, map, commonOperateDao);
            Type type1 = new TypeToken<ResponseData<SaveData>>() {
            }.getType();
            response = gson.fromJson(auditData.getBody(), type1);
            if (response.getErrcode() == 0) {
                log.info("反审核：审核生产任务成功");
                log.info("反审核：审核生产任务单Code: {}", response.getErrcode());
                log.info("反审核：审核生产任务单Message: {}", response.getDescription());
                log.info("反审核：审核生产任务单data: {}", response.getData());
            } else {
                log.error("反审核：审核生产任务单失败. Errcode: {}, Description: {}", response.getErrcode(), response.getDescription());
            }
        } catch (Exception e) {
            log.error("反审核：Error occurred while auditing sales order", e);
        }
        responseData = response;
        log.info("反审核返回：responseData=" + responseData);
        return responseData;
    }

    @SneakyThrows
    private List<DJOrderItem> selectDJOrderList() {
        DJOrderListParam djOrderListParam = new DJOrderListParam();
        djOrderListParam.setErpCode(ERP_CODE);
        LocalDateTime now = LocalDateTime.now();
        //LocalDateTime now = LocalDateTime.of(2025, 6, 5, 21, 20, 0);
        long startDate = now.minusMinutes(60).toInstant(ZoneOffset.ofHours(8)).toEpochMilli();
        long endDate = now.toInstant(ZoneOffset.ofHours(8)).toEpochMilli();
        djOrderListParam.setAnswerStartDate(startDate);
        djOrderListParam.setAnswerEndDate(endDate);
        String url = "https://openapi.xiekeyun.com/purchase/list.json";
        String response = XKYClient.sendRequest(url, djOrderListParam);
        BaseXKYListResponse<DJOrderItem> xkyListResponse = JSONObject.parseObject(response, new TypeReference<BaseXKYListResponse<DJOrderItem>>() {
        }.getType());
        return xkyListResponse.getDataList();
    }

    @SneakyThrows
    private PurchaseOrderDetail selectPurchaseOrderDetail(String poErpNo) {
        PurchaseOrderDetailParam purchaseOrderDetailParam = new PurchaseOrderDetailParam();
        purchaseOrderDetailParam.setErpCode(ERP_CODE);
        purchaseOrderDetailParam.setPoErpNo(poErpNo);
        String url = "https://openapi.xiekeyun.com/purchase/getDetail.json";
        String response = XKYClient.sendRequest(url, purchaseOrderDetailParam);
        BaseXKYObjResponse<PurchaseOrderDetail> xkyObjResponse = JSONObject.parseObject(response, new TypeReference<BaseXKYObjResponse<PurchaseOrderDetail>>() {
        }.getType());
        return xkyObjResponse.getData();
    }

    private PurOrderDetailData selectERPPurOrderDetail(String number) {
        PurOrderDetailData purOrderDetailData;
        Gson gson = new Gson();
        log.info("根据编号获取采购订单");
        HashMap<String, String> map = new HashMap<>();
        map.put("number", number);
        DataServiceImpl Service = new DataServiceImpl();
        ApiResult DataResult = null;
        try {
            DataResult = Service.SelectDataList(Constants.PUR_ORDER_DETAIL, map, "");
            Type SaleDataType = new TypeToken<ResponseData<PurOrderDetailData>>() {
            }.getType();
            ResponseData<PurOrderDetailData> responseSaleData = gson.fromJson(DataResult.getBody(), SaleDataType);
            purOrderDetailData = responseSaleData.getData();
            log.info("code {}", responseSaleData.getErrcode());
            log.info("描述 {}", responseSaleData.getDescription());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return purOrderDetailData;
    }

    private void setBillDate(PurOrderRequest purOrderRequest, PurchaseOrderDetail purchaseOrderDetail) {
        Long erpPurchaseDate = purchaseOrderDetail.getErpPurchaseDate();
        purOrderRequest.setBill_date(LocalDateTime.ofEpochSecond(erpPurchaseDate / 1000, 0, ZoneOffset.ofHours(8)).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
    }

    @SneakyThrows
    private void setSupplier(PurOrderRequest purOrderRequest, PurchaseOrderDetail purchaseOrderDetail) {
        DataServiceImpl service = new DataServiceImpl();
        SupplierServiceImpl departmentService = new SupplierServiceImpl();
        SupplierData supplierData = departmentService.getSupplier(service, purchaseOrderDetail.getInnerVendorName());
        purOrderRequest.setSupplier_id(supplierData.getId());
        purOrderRequest.setSupplier_number(supplierData.getNumber());
    }

    @SneakyThrows
    private void materialEntity(PurOrderRequest purOrderRequest, PurchaseOrderDetail purchaseOrderDetail) {
        List<MaterialEntity> materialEntities = new ArrayList<>();
        for (ProductLineItem lineItem : purchaseOrderDetail.getLineList()) {
            MaterialEntity materialEntity = new MaterialEntity();
            Number expectedDate = lineItem.getExpectedDate();
            materialEntity.setDelivery_date(LocalDateTime.ofEpochSecond(expectedDate.longValue() / 1000, 0, ZoneOffset.ofHours(8)).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            MaterialData materialData = getMaterialData(lineItem);
            materialEntity.setMaterial_id(materialData.getId());
            materialEntity.setMaterial_number(materialData.getNumber());
            materialEntity.setMaterial_name(materialData.getName());
            materialEntity.setQty(lineItem.getPurchaseQty());
            materialEntity.setUnit_id(materialData.getBase_unit_id());
            materialEntity.setBase_unit_number(materialData.getBase_unit_number());
            materialEntity.setPrice(lineItem.getTaxPrice().toString());

            materialEntities.add(materialEntity);
        }

        purOrderRequest.setMaterial_entity(materialEntities);
    }

    private MaterialData getMaterialData(ProductLineItem lineItem) {
        int page = 1; // 初始页码
        int pageSize = 10; // 每页记录数
        HashMap<String, String> map = new HashMap<>();
        map.put("page", String.valueOf(page));
        map.put("page_size", String.valueOf(pageSize));
        map.put("search", lineItem.getProductCode());
        ApiResult detailMateria = null;
        try {
            DataServiceImpl service = new DataServiceImpl();
            detailMateria = service.SelectDataList(Constants.MATERIAL_PATH, map, "");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        Type MateriaDataType = new TypeToken<ResponseData<GenericDataItem<MaterialData>>>() {
        }.getType();
        ResponseData<GenericDataItem<MaterialData>> detailMaterialData = gson.fromJson(detailMateria.getBody(), MateriaDataType);
        GenericDataItem<MaterialData> data = detailMaterialData.getData();
        List<MaterialData> rows = data.getRows();
        for (MaterialData row : rows) {
            if (Objects.equals(row.getNumber(), lineItem.getProductCode())) {
                return row;
            }
        }
        return null;
    }

    @SneakyThrows
    private void updateSyncStatus(PurchaseOrderDetail purchaseOrderDetail, ApiResult insertResult) {
        Type type = new TypeToken<ResponseData<SaveData>>() {
        }.getType();
        ResponseData<SaveData> saveDataResponse = gson.fromJson(insertResult.getBody(), type);
        UpdatePoErpNoParam updatePoErpNoParam = new UpdatePoErpNoParam();
        updatePoErpNoParam.setErpCode(ERP_CODE);
        updatePoErpNoParam.setPoXkNo(purchaseOrderDetail.getPoXkNo());
        if (saveDataResponse.getErrcode() == 0) {
            // 成功
            updatePoErpNoParam.setPoErpNo(getErpCode(saveDataResponse));
            String url = "https://openapi.xiekeyun.com/purchase/updatePoErpNo.json";
            String response = XKYClient.sendRequest(url, updatePoErpNoParam);
            log.info("response:{}", response);
        }
    }

    private String getErpCode(ResponseData<SaveData> saveDataResponse) {
        SaveData saveData = saveDataResponse.getData();
        return saveData.getId_number_map().get(saveData.getIds().get(0));
    }

    public static void main(String[] args) {
        XKYDJOrderController xkyPurchaseOrderController = new XKYDJOrderController();
        xkyPurchaseOrderController.selectDJOrder();
    }
}
